#pragma once

#include "ThreadPool/Log.hpp"
#include <iostream>
#include <unistd.h>
#include <string>
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <unistd.h>

class TcpClient
{
public:
    TcpClient(const std::string& ip, uint16_t port)
        : _ip(ip), _port(port), _sock(-1)
    { }

    // 初始化客户端
    void init()
    {
        // 创建socket文件描述符
        _sock = socket(AF_INET, SOCK_STREAM, 0);
        if(_sock < 0)
        {
            logMessage(FATAL, "socket error, %d:%s\n", errno, strerror(errno));
            exit(2);
        }
        logMessage(NORMAL, "socket success, _sock:%d\n", _sock);

        // 客户端与服务端连接
        struct sockaddr_in sock_srv;
        memset(&sock_srv, 0, sizeof(sock_srv));
        sock_srv.sin_family = AF_INET;
        sock_srv.sin_addr.s_addr = inet_addr(_ip.c_str());
        sock_srv.sin_port = htons(_port);
        socklen_t len = sizeof(sock_srv);

        if(connect(_sock, (struct sockaddr *)&sock_srv, len) < 0)
        {
            logMessage(FATAL, "connect error, %d:%s\n", errno, strerror(errno));
            exit(3);
        }

        logMessage(NORMAL, "connect success\n");
        logMessage(NORMAL, "Client Init Success\n");

    }

    void start()
    {
        std::string msg;    // 发送的消息
        char buffer[1024];  // 接受服务器发回的消息

        while(true)
        {
            std::cout << "请输入你要发送的消息: " << std::flush;
            std::getline(std::cin, msg);

            if(msg == "quit")
                break;

            ssize_t n = send(_sock, msg.c_str(), msg.size(), 0);
            if(n > 0)
            {
                logMessage(NORMAL, "成功发送数据！\n");
                ssize_t s = recv(_sock, buffer, 1023, 0);
                if(s > 0)
                {
                    buffer[s] = '\0';
                    printf("回显# %s\n", buffer);
                }
                else if(s == 0)
                {
                    logMessage(DEBUG, "服务器退出!\n");
                    break;
                }
                else
                {
                    logMessage(DEBUG, "获取服务器发回数据失败!\n");
                    continue;
                }
            }
        }
    }

    ~TcpClient()
    {
        if(_sock < 0)
        {
            close(_sock);
        }
    }

private:
    std::string _ip;
    uint16_t _port;
    int _sock;
};